// 通过内容计算md5值
/*
spark-md5，它可以根据文件内容计算出文件的 hash 值，
另外考虑到如果上传一个超大文件，
读取文件内容计算 hash 是非常耗费时间的，
并且会引起 UI 的阻塞，导致页面假死状态，
所以我们使用 web-worker 在 worker 线程计算 hash，
这样用户仍可以在主界面正常的交互
可以看看 README.md文件
*/

/*
spark-md5 需要根据所有切片才能算出一个 hash 值，
不能直接将整个文件放入计算，
否则即使不同文件也会有相同的 hash，具体可以看官方文档
*/

self.importScripts('./spark-md5.min.js'); // 导入脚本

self.onmessage = (e) => {

    //  console.log(e);
    // self.postMessage({ //向主线程通信返回信息
    //     msg: '你好~'
    // })
    const { fileChunkList } = e.data;
    // console.log("-----");
    // console.log(fileChunkList);
    const spark = new self.SparkMD5.ArrayBuffer();
    let percentage = 0;
    let count = 0;

    /*API可能有点不同
    这里提供了两个方法；
    1. 一种是用SparkMD5.hashBinary( ) 直接将整个文件的二进制码传入直接返回文件的md5、
    这种方法对于小文件会比较有优势——简单并且速度快。
    2. 另一种方法是利用js中File对象的slice( )方法（File.prototype.slice( )）
    将文件分片后逐个传入spark.appendBinary( )方法来计算、
    最后通过spark.end( )方法输出结果，
    很明显，这种方法对于大型文件会非常有利——不容易出错，并且能够提供计算的进度信息
    */
    //计算出hash
    const loadNext = (index) => {
        const reader = new FileReader();
        reader.readAsArrayBuffer(fileChunkList[index].file)
        // console.log(reader);
        reader.onload = e => { //读到一个文件后
            count++;
            spark.append(e.target.result);
            if (count === fileChunkList.length) {
                self.postMessage({
                    percentage: 100,
                    hash: spark.end()
                });
                self.close()
            } else {
                //还没读完
                percentage = count / fileChunkList.length * 100;
                // 或 percentage += 100/fileChunkList.length;
                self.postMessage({//每完成一个发送一次消息返回给主线程，得到好的反馈
                    percentage
                });
                // 递归计算下一个切片
                loadNext(count);
            }
        }
    }
    loadNext(count) //第一次为0，故可写为 loadNext(0);


} // this 当前的线程